package com.wumart.scaffold.web.base.global;


import com.wumart.scaffold.web.common.enums.CodeMsg;
import com.wumart.scaffold.web.common.exception.HasNoVenderException;
import com.wumart.scaffold.web.common.exception.NotLoginException;
import com.wumart.scaffold.web.common.response.HttpResult;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.MethodParameter;
import org.springframework.core.annotation.Order;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.lang.Nullable;
import org.springframework.validation.BindException;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.stream.Collectors;

/**
 * @author wancheng on 2019/3/20.
 */
@RestControllerAdvice
@Order()
public class GlobalResponseBodyAdvice implements ResponseBodyAdvice {

    private final static Logger logger = LoggerFactory.getLogger(GlobalResponseBodyAdvice.class);

    private final static String DESCRIPTION_SUCCESS = "%s : success";
    private final static String DESCRIPTION_ERROR = "%s : error";

    /**
     * 对象参数bind 异常
     *
     * @param request
     * @param ex
     * @return
     */
    @ExceptionHandler(BindException.class)
    public HttpResult<String> exceptionHandler(HttpServletRequest request, BindException ex) {
        String url = request.getRequestURI();
        String errorMesssage = "校验失败:" + ex.getFieldErrors()
                .stream()
                .map(FieldError::getDefaultMessage)
                .collect(Collectors.joining(","));
        return HttpResult.failure(CodeMsg.ERR_HAS_NO_VENDER_EXEC,errorMesssage);
    }



    /**
     * 全局异常处理
     *
     * @param request
     * @param ex
     * @return
     */
    @ExceptionHandler(Exception.class)
    public HttpResult<String> globalControllerException(HttpServletRequest request, HttpServletResponse response, Exception ex) {
        logger.error("", ex);
        if (ex instanceof NotLoginException){
            return HttpResult.failure(CodeMsg.ERR_NEED_LOGIN_EXEC);
        }else if (ex instanceof HasNoVenderException){
            return HttpResult.failure(CodeMsg.ERR_HAS_NO_VENDER_EXEC);
        }else {
            return HttpResult.failure("error:" + ex.getMessage());
        }
    }

    @Override
    public boolean supports(MethodParameter methodParameter, Class aClass) {
        if ("serveFile".equals(methodParameter.getMethod().getName())) {
            return false;
        }
        return true;
    }

    @Override
    public Object beforeBodyWrite(@Nullable Object o, MethodParameter methodParameter, MediaType mediaType, Class aClass, ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse) {
        RequestMapping r = methodParameter.getExecutable().getAnnotation(RequestMapping.class);
        String methodDescription = "";
        if (r != null) {
            methodDescription = r.name();
        }
         if (o instanceof ResponseEntity) {
            return o;
        }else if (o instanceof HttpResult) {
            return o;
        } else {
            return HttpResult.success(String.format(DESCRIPTION_SUCCESS, methodDescription), o);
        }
    }

}
